package com.young.ums.service.impl;

import com.young.common.exception.BaseException;
import com.young.common.exception.ParamException;
import com.young.common.util.CommonUtil;
import com.young.common.core.dal.service.IDataAccessService;
import com.young.common.util.Page;
import com.young.common.util.StringUtils;
import com.young.interfaces.log.annotation.Log;
import com.young.ums.model.PersonInfoVO;
import com.young.ums.model.User;
import com.young.ums.core.ETopic;
import com.young.ums.core.PublishSubscribeCenter;
import com.young.common.model.enums.ETrashFlagEnum;
import com.young.ums.model.enums.EUserStateEnum;
import com.young.ums.service.*;
import com.young.ums.util.SecureHandler;
import com.young.ums.util.UmsConstants;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
* 用户信息服务实现
* Created by rookie on 2018-04-03.
*/
@Service("userService")
public class UserServiceImpl implements IUserService {

    @Resource(name = "dataAccessService")
    IDataAccessService dataAccessService;//数据层服务

    @Resource(name="umsConfigService")
    IUmsConfigService configService;

    @Resource
    ILoginLogService loginLogService;//登录日志服务

    @Resource
    PublishSubscribeCenter publishSubscribeCenter;

    @Resource(name = "dataAuthService")
    IDataAuthService dataAuthService;

    @Resource
    IRoleUserService roleUserService;

    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    private static final String MAPPER = "com.young.ums.mapper.user";//mapper的namespace

    //获取数据列表
    @Log("查询用户列表")
    @Override
    public List<User> getList(User obj) {
        //权限参数处理
        dataAuthService.handleAuthorityParameter(obj);
        return dataAccessService.getList(MAPPER + ".getList", obj);
    }

    /**
     * 用户树查询(只返回树需要的字段)
     *
     * @param obj
     * @return
     */
    @Log("用户树查询")
    @Override
    public List<User> getListAsTree(User obj) {
        //权限参数处理
        dataAuthService.handleAuthorityParameter(obj);
        return dataAccessService.getList(MAPPER + ".getListAsTree", obj);
    }

    //获取数据列表(分页)
    @Log("分页查询用户")
    @Override
    public List<User> getPage(User obj, Page page) {
        //权限参数处理
        dataAuthService.handleAuthorityParameter(obj);
        return dataAccessService.getList(MAPPER + ".getList", obj, page);
    }

    /**
     * 根据单位id查询用户列表
     *
     * @param companyId 单位id
     * @return
     */
    @Log("根据单位id查询用户列表")
    @Override
    public List<User> getListByCompanyId(String companyId) {
        if (StringUtils.isBlank(companyId)){
            return null;
        }
        User obj = new User();
        obj.setCompanyId(companyId);
        return this.getList(obj);
    }

    //查询单条
    @Log("查询用户")
    @Override
    public User get(String id) {
        return dataAccessService.getObject(MAPPER + ".get", id);
    }

    //没有Log的查询, 给ums拦截器定制
    @Override
    public User getNoLog(String id) {
        return dataAccessService.getObject(MAPPER + ".get", id);
    }

    @Log("查询个人信息")
    @Override
    public PersonInfoVO queryPersonInfo(String userId) {
        PersonInfoVO personInfoVO = new PersonInfoVO();
        //查询个人信息
        User user = this.get(userId);
        if (user == null){
            return null;
        }
        personInfoVO.setUserInfo(user);
        //查询用户的登录次数
        if (StringUtils.isNotBlank(user.getAccount())){
            personInfoVO.setLoginNum(loginLogService.countByAccount(user.getAccount()));
        }
        //todo 日志数量和消息数量
        return personInfoVO;
    }

    @Log("根据账号查询用户")
    @Override
    public User getUserByAccount(String account) {
        return dataAccessService.getObject(MAPPER + ".getUserByAccount", account);
    }

    //统计数量
    @Log("根据条件查询用户数量")
    @Override
    public int count(User obj) {
        return dataAccessService.getObject(MAPPER + ".count", obj);
    }

    //修改
    @Log("更新用户")
    @Override
    public int update(User obj) {
        obj.setUpdateTime(new Date());
        return dataAccessService.update(MAPPER + ".update", obj);
    }

    //更新用户登录时间
    @Log("更新登录时间")
    @Override
    public int updateLoginTime(String userId, Date loginTime) {
        User user = new User();
        user.setId(userId);
        user.setThisLoginTime(loginTime);
        user.setUpdateTime(new Date());
        return dataAccessService.update(MAPPER + ".updateLoginTime", user);
    }

    //批量删除
    @Log("批量删除用户")
    @Override
    public int delete(String[] idArr) {
        int i = 0;
        for(String id : idArr){
            i += this.delete(id);
        }
        return i;
    }

    //删除单条
    @Log("删除用户")
    @Override
    public int delete(String id) {
        //向发布订阅中心发布用户删除消息
        publishSubscribeCenter.publish(ETopic.USER_DEL, id);
        return dataAccessService.delete(MAPPER + ".delete", id);
    }

    /**
     * 判断账号是否存在
     * @param account
     * @return
     */
    private boolean existAccount(String account) {
        User searchParam = new User();
        searchParam.setAccount(account);
        //根据账号查询用户数
        int num = this.count(searchParam);
        return num > 0;
    }

    //插入
    @Log("插入用户信息")
    @Override
    public int insert(User obj) {
        if (StringUtils.isBlank(obj.getAccount())) {
            throw new ParamException("账号不允许为空");
        }
        //判断账号是否被使用
        if (this.existAccount(obj.getAccount())) {
            throw new ParamException("账号已存在!");
        }

        // 默认id等于账号
        if (StringUtils.isBlank(obj.getId())) {
            String userIdEqAccount = configService.getUsableConfigValueElse(UmsConstants.UmsConfigKey.USER_ID_EQ_ACCOUNT, "true");
            if (Boolean.TRUE.toString().equals(userIdEqAccount)) {
                obj.setId(obj.getAccount());
            } else {
                obj.setId(CommonUtil.getUUID());
            }
        }

        obj.setCreateTime(new Date());
        obj.setUpdateTime(new Date());
        if (obj.getState() == null) {
            obj.setState(EUserStateEnum.ENABLE.state);//用户状态有效
        }
        obj.setTrashFlag(ETrashFlagEnum.VALID.type);//未删除
        //默认单位为NON
        if (StringUtils.isBlank(obj.getCompanyId())){
            obj.setCompanyId(UmsConstants.DEFAULT.NON_DEPT);
        }
        //设置初始密码
        if (StringUtils.isBlank(obj.getPassword())){//密码为空，设置默认密码
            obj.setPassword(configService.getUsableConfigValue(UmsConstants.UmsConfigKey.USER_DEFAULT_PASSWORD));
        }
        //密码加密
        obj.setPassword(SecureHandler.encryptPwd(obj.getPassword()));
        return dataAccessService.insert(MAPPER + ".insert", obj);
    }

    /**
     * 插入用户并分配角色
     *
     * @param obj
     * @param roleIds
     * @return
     */
    @Log("插入用户并分配角色")
    @Override
    public int insertUserAndSetRole(User obj, String[] roleIds) {
        int num = this.insert(obj);//插入用户
        if (roleIds != null && roleIds.length > 0) {
            //分配角色给用户
            roleUserService.relevanceRoles2User(obj.getId(), roleIds);
        }
        return num;
    }

    //批量插入
    @Log("批量插入用户")
    @Override
    public int batchInsert(List<User> list) {
        int i = 0;
        for(User item : list){
            i += this.insert(item);
        }
        return i;
    }

    //重置密码
    @Log("重置密码")
    @Override
    public int resetPassword(String userId) {
        User user = new User();
        user.setId(userId);
        String defaultPwd = configService.getUsableConfigValue(UmsConstants.UmsConfigKey.USER_DEFAULT_PASSWORD);
        user.setPassword(SecureHandler.encryptPwd(defaultPwd));
        return this.update(user);
    }

    //批量重置密码
    @Log("批量重置密码")
    @Override
    public int batchResetPassword(String[] userIds) {
        int i = 0;
        for(String userId : userIds){
            i += this.resetPassword(userId);
        }
        return i;
    }

    /**
     * 修改密码
     *
     * @param userId 用户id
     * @param oldPwd 旧密码
     * @param newPwd 新密码
     * @return
     */
    @Log("修改密码")
    @Override
    public int updatePassword(String userId, String oldPwd, String newPwd) {
        //根据userid查询用户信息
        User userInfo = this.get(userId);
        if (userInfo == null){
            throw new BaseException("用户信息无效");
        }
        if (!SecureHandler.encryptPwd(oldPwd).equals(userInfo.getPassword())){
            throw new BaseException("旧密码错误");
        }
        return this.resetNewPassword(userId, newPwd);
    }

    /**
     * 重置密码
     *
     * @param userId
     * @param newPwd
     * @return
     */
    @Log("重置密码")
    @Override
    public int resetNewPassword(String userId, String newPwd) {
        User user = new User();
        user.setId(userId);
        user.setPassword(SecureHandler.encryptPwd(newPwd));
        return dataAccessService.update(MAPPER + ".updatePassword", user);
    }

    /**
     * 清空密码找回key
     *
     * @param userId 用户id
     * @return
     */
    @Log("清空密码找回key")
    @Override
    public int clearFindPwdKey(String userId) {
        return dataAccessService.update(MAPPER + ".clearFindPwdKey", userId);
    }

    /**
     * 更新密码找回的key
     *
     * @param userId       用户id
     * @param findKey      密码找回的key
     * @param findDeadline 找回截止时间
     * @return
     */
    @Log("更新密码找回的key")
    @Override
    public int updateFindPwdKey(String userId, String findKey, Date findDeadline) {
        User user = new User();
        user.setId(userId);
        user.setFindPwdKey(findKey);
        user.setFindPwdDeadline(findDeadline);
        return dataAccessService.update(MAPPER + ".updateFindPwdKey", user);
    }

    /**
     * 根据密码找回key查询用户
     *
     * @param key 密码找回key
     * @return
     */
    @Override
    public User getByFindPwdKey(String key) {
        User user = new User();
        user.setFindPwdKey(key);
        return dataAccessService.getObject(MAPPER + ".getByFindPwdKey", user);
    }

}